package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.types.ImageData


////////////////////
// Extension Types
////////////////////
/** The `Browser.extensionTypes` API contains type declarations for Chrome extensions. */

interface ExtensionTypes {
    // The origin of injected CSS.
    @ChromeMinVersion(66)
    enum class CSSOrigin {
        author,
        user
    }

    // The document lifecycle of the frame.
    @ChromeMinVersion(106)
    enum class DocumentLifecycle {
        prerender,
        active,
        cached,
        pending_eletion
    }

    @ChromeMinVersion(106)
    enum class FrameType {
        outermost_frame,
        fenced_frame,
        sub_frame
    }

    // Details about the format, quality, and area of an image.
    data class ImageDetails(
        // The format of the resulting image. Default is "jpeg".
        var format: ImageFormat? = ImageFormat.jpeg,
        // When format is "jpeg", controls the quality of the resulting image. This value is ignored for PNG images.
        // As quality is decreased, the resulting image will have more visual artifacts,
        // and the number of bytes needed to store it will decrease.
        var quality: Number? = null,
    )

    @ChromeMinVersion(44)
    enum class ImageFormat {
        jpeg,
        png
    }

    // The JavaScript world for a script to execute within.
    // Can either be an isolated world unique to this extension, the main world of the DOM which is shared with the page's JavaScript,
    // or a user scripts world that is only available for scripts registered with the User Scripts API.
    @ChromeMinVersion(111)
    enum class ExectionWorld {
        ISOLATED,
        MAIN,
        USER_SCRIPT
    }

    // Details of the CSS to remove. Either the code or the file property must be set,
    // but both may not be set at the same time.
    @ChromeMinVersion(87)
    data class DeleteInjectionDetails(
        // If allFrames is true, implies that the CSS should be removed from all frames of current page.
        // By default, it's false and is only removed from the top frame.
        // If true and frameId is set, then the code is removed from the selected frame and all of its child frames.
        var allFrames: Boolean? = null,
        // CSS code to remove.
        var code: String? = null,
        // The origin of the CSS to remove. Defaults to "author".
        var cssOrigin: CSSOrigin? = CSSOrigin.author,
        // CSS file to remove.
        var file: String? = null,
        // The frame from where the CSS should be removed. Defaults to 0 (the top-level frame).
        var frameId: Number? = null,
        // If matchAboutBlank is true, then the code is also removed from about:blank and about:srcdoc frames
        // if your extension has access to its parent document.
        // By default it is false.
        var matchAboutBlank: Boolean? = false
    )

    // Details of the script or CSS to inject. Either the code or the file property must be set,
    // but both may not be set at the same time.
    data class InjectDetails(
        //  If allFrames is true, implies that the JavaScript or CSS should be injected into all frames of current page.
        //  By default, it's false and is only injected into the top frame.
        //  If true and frameId is set, then the code is inserted in the selected frame and all of its child frames.
        var allFrames: Boolean? = null,
        // JavaScript or CSS code to inject.
        //
        //Warning: Be careful using the code parameter. Incorrect use of it may open your extension to cross site scripting attacks
        var code: String? = null,
        // The origin of the CSS to remove. Defaults to "author".
        @ChromeMinVersion(66)
        var cssOrigin: CSSOrigin? = CSSOrigin.author,
        // JavaScript or CSS file to inject.
        var file: String? = null,
        // The frame where the script or CSS should be injected. Defaults to 0 (the top-level frame).
        @ChromeMinVersion(50)
        var frameId: Number? = null,
        // If matchAboutBlank is true, then the code is also injected in about:blank and about:srcdoc frames if your extension has access to its parent document.
        // Code cannot be inserted in top-level about:-frames. By default it is false.
        var matchAboutBlank: Boolean? = false,
        // The soonest that the JavaScript or CSS will be injected into the tab. Defaults to "document_idle".
        @ChromeMinVersion(44)
        var runAt: RunAt? = RunAt.document_idle
    )

    // The soonest that the JavaScript or CSS will be injected into the tab.
    @ChromeMinVersion(44)
    enum class RunAt {
        // Script is injected after any files from css, but before any other DOM is constructed or any other script is run.
        document_start,

        //The browser chooses a time to inject the script between "document_end" and immediately after the window.onload event fires.
        // The exact moment of injection depends on how complex the document is and how long it is taking to load,
        // and is optimized for page load speed.
        // Content scripts running at "document_idle" don't need to listen for the window.onload event;
        // they are guaranteed to run after the DOM completes.
        // If a script definitely needs to run after window.onload,
        // the extension can check if onload has already fired by using the document.readyState property.
        document_idle,

        // Script is injected immediately after the DOM is complete, but before subresources like images and frames have loaded.
        document_end
    }

}

// FIXME: limit size array rgba
@ChromeMinVersion(139)
typealias ColorArray = List<Int>

// Pixel data for an image. Must be an ImageData object; for example, from a canvas element.
@ChromeMinVersion(139)
typealias ImageDataType = ImageData





